package com.tarena.lbs.business.dao.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.business.dao.mapper.StoreMapper;
import com.tarena.lbs.business.dao.repository.StoreESRepository;
import com.tarena.lbs.business.dao.repository.StoreRepository;
import com.tarena.lbs.business.pojo.param.StoreParam;
import com.tarena.lbs.business.pojo.param.UserLocationParam;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.query.StoreQuery;
import com.tarena.lbs.business.pojo.vo.PictureVO;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.common.exception.ServiceException;
import com.tarena.lbs.common.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Repository
@Slf4j
public class StoreRepositoryImpl implements StoreRepository {
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private StoreESRepository storeESRepository;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Integer save(StoreParam param) {
        StorePO po = new StorePO();
        po.setId(param.getId());
        po.setBusinessId(param.getBusinessId());
        po.setStoreName(param.getStoreName());
        po.setStorePhone(param.getStorePhone());
        po.setStoreHeadName(param.getStoreHeadName());
        po.setStoreHeadPhone(param.getStoreHeadPhone());
        po.setProvinceId(param.getProvinceId());
        po.setAreaId(param.getAreaId());
        po.setCityId(param.getCityId());
        po.setStoreLocation(param.getStoreLocation());
        po.setStoreLongitude(param.getStoreLongitude());
        po.setStoreLatitude(param.getStoreLatitude());
        po.setStoreImagesId(String.join(",", param.getStoreImagesIds()));
        po.setStoreLogo(param.getStoreLogo());
        po.setStoreIntroduction(param.getStoreIntroduction());
        po.setSort(param.getSort());
        po.setTradeTime(param.getTradeTime());
        po.setStoreStatus(param.getStoreStatus());
        po.setCreateTime(new Date());
        log.info("保存店铺信息:{}", po);
        Integer id = storeMapper.insert(po);
        storeESRepository.save(po);
        
        // 将店铺信息存入Redis缓存
        redisTemplate.opsForValue().set("store:" + id, po);
        return id;
    }

    @Override
    public List<StoreVO> select(StoreQuery query) {
        log.debug("查询店铺信息:{}", query);
        QueryWrapper queryWrapper = new QueryWrapper<>();
        
        // 根据query中的值是否为空来构建查询条件
        if (StringUtils.hasText(query.getStoreName())) {
            queryWrapper.like("store_name", query.getStoreName());
        }
        
        if (StringUtils.hasText(query.getStoreHeadPhone())) {
            queryWrapper.eq("store_head_phone", query.getStoreHeadPhone());
        }
        
        if (query.getProvinceId() != null) {
            queryWrapper.eq("province_id", query.getProvinceId());
        }
        
        if (query.getAreaId() != null) {
            queryWrapper.eq("area_id", query.getAreaId());
        }
        
        if (query.getBusinessId() != null) {
            queryWrapper.eq("business_id", query.getBusinessId());
        }
        
        if (query.getCityId() != null) {
            queryWrapper.eq("city_id", query.getCityId());
        }
        
        if (query.getStartingTime() != null) {
            queryWrapper.ge("update_time", query.getStartingTime());
        }
        
        if (query.getEndTime() != null) {
            queryWrapper.le("update_time", query.getEndTime());
        }
        
        if (query.getStoreStatus() != null) {
            queryWrapper.eq("store_status", query.getStoreStatus());
        }

        List<StoreVO> pos = storeMapper.selectList(queryWrapper);
        return pos;
    }

    @Override
    public List<StoreVO> selectByCityId(Long cityId) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("city_id", cityId);
        List<StorePO> po = storeMapper.selectList(queryWrapper);
        if (po == null || po.isEmpty()) {
            throw new ServiceException(StatusCode.NULL_STORE);
        }

        List<StoreVO> voList = new ArrayList<>();
        for (int i = 0; i < po.size(); i++) {
            StoreVO vo = new StoreVO();
            StorePO storePO = po.get(i);
            BeanUtils.copyProperties(storePO, vo);

            // 处理图片ID字符串 "1,2"
            List<PictureVO> pictureVOList = new ArrayList<>();
            String[] imageIds = storePO.getStoreImagesId().split(",");
            for (int j = 0; j < imageIds.length; j++) {
                PictureVO pictureVO = new PictureVO();
                pictureVO.setId(j + 1);
                pictureVO.setImage(imageIds[j].trim()); // 添加trim()去除空格
                pictureVOList.add(pictureVO);
            }

            // 关键：将 pictureVOList 设置到 vo 中
            vo.setPictureVOS(pictureVOList); // 假设 StoreVO 中有 setPictures 方法

            voList.add(vo);
        }
        return voList;
    }

    @Override
    public boolean saveUserLocation(UserLocationParam param) {
        // 保存用户位置信息到Redis
        //1.操作的redis的数据肯定是geo key charging:all:stations.geo value id
        GeoOperations<String, Integer> geoOps = redisTemplate.opsForGeo();
        Integer id = param.getUserId();
        Double lng = Double.valueOf(param.getLongitude());
        Double lat = Double.valueOf(param.getLatitude());
        // 使用正确的Point类
        Point point = new Point(lng, lat);
        RedisGeoCommands.GeoLocation<Integer> location = new RedisGeoCommands.GeoLocation<>(id, point);
        //3.调用geoOps操作对象的api
        Long result=geoOps.add("user:location:geo", location);
        log.info("用户位置:{}",location);
        if (result>0L){
            return true;
        }else {
            return false;
        }
    }
}